{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e42071e4",
   "metadata": {},
   "source": [
    "# Gradient Descent Optimizers\n",
    "\n",
    "[![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/brainpy/brainpy/blob/master/docs_version2/tutorial_toolbox/optimizers.ipynb)\n",
    "[![Open in Kaggle](https://kaggle.com/static/images/open-in-kaggle.svg)](https://kaggle.com/kernels/welcome?src=https://github.com/brainpy/brainpy/blob/master/docs_version2/tutorial_toolbox/optimizers.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "355bb9b6",
   "metadata": {},
   "source": [
    "@[Chaoming Wang](https://github.com/chaoming0625)\n",
    "@[Xiaoyu Chen](mailto:c-xy17@tsinghua.org.cn)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "95b9589c",
   "metadata": {},
   "source": [
    "Gradient descent is one of the most popular optimization methods. At present, gradient descent optimizers, combined with the loss function, are the key to machine learning, especially deep learning. In this section, we are going to understand:\n",
    "\n",
    "- how to use optimizers in BrainPy?\n",
    "- how to customize your own optimizer?"
   ]
  },
  {
   "cell_type": "code",
   "id": "a9813ba0",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:03.506031Z",
     "start_time": "2025-10-06T05:15:03.497322Z"
    }
   },
   "source": [
    "import brainpy as bp\n",
    "import brainpy.math as bm\n",
    "\n",
    "bp.math.set_platform('cpu')\n",
    "bp.__version__"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'3.0.0'"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 34
  },
  {
   "cell_type": "code",
   "id": "92b9cd6d",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:03.547676Z",
     "start_time": "2025-10-06T05:15:03.543662Z"
    }
   },
   "source": [
    "import matplotlib.pyplot as plt"
   ],
   "outputs": [],
   "execution_count": 35
  },
  {
   "cell_type": "markdown",
   "id": "e62bdc0d",
   "metadata": {},
   "source": [
    "## Optimizers in BrainPy"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "712cb717-fd31-4711-a0cc-aaa43bf9d62a",
   "metadata": {},
   "source": [
    "The basic optimizer class in BrainPy is `brainpy.optimizers.optimizer`, which inludes the following optimizers:\n",
    "\n",
    "- SGD\n",
    "- Momentum\n",
    "- Nesterov momentum\n",
    "- Adagrad\n",
    "- Adadelta\n",
    "- RMSProp\n",
    "- Adam\n",
    "- LARS\n",
    "- Adan\n",
    "- AdamW\n",
    "\n",
    "All supported optimizers can be inspected through the [brainpy.math.optimizers APIs](../apis/auto/optimizers.rst)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "05adb1c4",
   "metadata": {},
   "source": [
    "Generally, an optimizer initialization receives the learning rate ``lr``, the trainable variables ``train_vars``, and other hyperparameters for the specific optimizer.  \n",
    "\n",
    "- ``lr`` can be an instance of float,``bm.Variable`` or ``brainpy.optim.scheduler``. However, whether it's an instance of float or ``bm.Variable``, it will be transformed to be an instance of ``brainpy.optim.Constant`` automatically, which is a class of scheduler. Therefore, the users have to  understand the type of ``lr`` is actually scheduler.\n",
    "- ``train_vars`` should be a dict of Variable."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "180c2314",
   "metadata": {},
   "source": [
    "Here we launch a SGD optimizer."
   ]
  },
  {
   "cell_type": "code",
   "id": "2d716811",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:03.569537Z",
     "start_time": "2025-10-06T05:15:03.554139Z"
    }
   },
   "source": [
    "a = bm.Variable(bm.ones((5, 4)))\n",
    "b = bm.Variable(bm.zeros((3, 3)))\n",
    "\n",
    "op = bp.optim.SGD(lr=0.001, train_vars={'a': a, 'b': b})"
   ],
   "outputs": [],
   "execution_count": 36
  },
  {
   "cell_type": "markdown",
   "id": "e9c3cb0d",
   "metadata": {},
   "source": [
    "When you try to update the parameters, you must provide the corresponding gradients for each parameter in the ``update()`` method. "
   ]
  },
  {
   "cell_type": "code",
   "id": "0d4449f3",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:03.581251Z",
     "start_time": "2025-10-06T05:15:03.574101Z"
    }
   },
   "source": [
    "op.update({'a': bm.random.random(a.shape), 'b': bm.random.random(b.shape)})\n",
    "\n",
    "print('a:', a)\n",
    "print('b:', b)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a: Variable(\n",
      "  value=ShapedArray(float32[5,4]),\n",
      "  _batch_axis=None,\n",
      "  axis_names=None\n",
      ")\n",
      "b: Variable(\n",
      "  value=ShapedArray(float32[3,3]),\n",
      "  _batch_axis=None,\n",
      "  axis_names=None\n",
      ")\n"
     ]
    }
   ],
   "execution_count": 37
  },
  {
   "cell_type": "markdown",
   "id": "f25554d5",
   "metadata": {},
   "source": [
    "You can process the gradients before applying them. For example, we clip the graidents by the maximum L2-norm. "
   ]
  },
  {
   "cell_type": "code",
   "id": "aad2ffcc",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:03.606313Z",
     "start_time": "2025-10-06T05:15:03.599032Z"
    }
   },
   "source": [
    "grads_pre = {'a': bm.random.random(a.shape), 'b': bm.random.random(b.shape)}\n",
    "\n",
    "grads_pre"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': Array([[0.76669514, 0.53197443, 0.18560624, 0.63484263],\n",
       "        [0.5859195 , 0.79874647, 0.04194212, 0.9483272 ],\n",
       "        [0.42012143, 0.9182961 , 0.06387115, 0.9356164 ],\n",
       "        [0.83041155, 0.31888366, 0.84094894, 0.20810902],\n",
       "        [0.23629928, 0.80462146, 0.71636903, 0.14623594]], dtype=float32),\n",
       " 'b': Array([[0.67210126, 0.14202476, 0.2031784 ],\n",
       "        [0.67333305, 0.6081852 , 0.8242061 ],\n",
       "        [0.8465828 , 0.47535837, 0.59738636]], dtype=float32)}"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 38
  },
  {
   "cell_type": "code",
   "id": "6f593769",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:03.629993Z",
     "start_time": "2025-10-06T05:15:03.623237Z"
    }
   },
   "source": [
    "grads_post = bm.clip_by_norm(grads_pre, 1.)\n",
    "\n",
    "grads_post"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': Array([[0.273306  , 0.18963446, 0.06616359, 0.22630417],\n",
       "        [0.2088644 , 0.28473145, 0.01495123, 0.33805293],\n",
       "        [0.14976189, 0.32734764, 0.02276833, 0.33352184],\n",
       "        [0.2960192 , 0.11367337, 0.29977548, 0.07418522],\n",
       "        [0.08423428, 0.28682572, 0.25536612, 0.05212915]], dtype=float32),\n",
       " 'b': Array([[0.36912522, 0.07800152, 0.11158776],\n",
       "        [0.36980173, 0.33402184, 0.45266286],\n",
       "        [0.46495235, 0.26107192, 0.328091  ]], dtype=float32)}"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 39
  },
  {
   "cell_type": "code",
   "id": "dba80baf",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:03.651006Z",
     "start_time": "2025-10-06T05:15:03.644762Z"
    }
   },
   "source": [
    "op.update(grads_post)\n",
    "\n",
    "print('a:', a)\n",
    "print('b:', b)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a: Variable(\n",
      "  value=ShapedArray(float32[5,4]),\n",
      "  _batch_axis=None,\n",
      "  axis_names=None\n",
      ")\n",
      "b: Variable(\n",
      "  value=ShapedArray(float32[3,3]),\n",
      "  _batch_axis=None,\n",
      "  axis_names=None\n",
      ")\n"
     ]
    }
   ],
   "execution_count": 40
  },
  {
   "cell_type": "markdown",
   "id": "05d98a0f",
   "metadata": {},
   "source": [
    "```{note}\n",
    "Optimizer usually has their own dynamically changed variables. If you JIT a function whose logic contains optimizer update, your ``dyn_vars`` in ``bm.jit()`` should include variables in ``Optimzier.vars()``.\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "id": "efc5c686",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:03.677233Z",
     "start_time": "2025-10-06T05:15:03.670058Z"
    }
   },
   "source": [
    "op.vars()  # SGD optimzier only has an iterable `step` variable to record the training step"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Constant9.last_epoch': Variable(\n",
       "   value=ShapedArray(int32[], weak_type=True),\n",
       "   _batch_axis=None,\n",
       "   axis_names=None\n",
       " )}"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 41
  },
  {
   "cell_type": "code",
   "id": "28965804",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:03.713161Z",
     "start_time": "2025-10-06T05:15:03.694555Z"
    }
   },
   "source": [
    "bp.optim.Momentum(lr=0.001, train_vars={'a': a, 'b': b}).vars()  # Momentum has velocity variables"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Momentum3.a_v': Variable(\n",
       "   value=ShapedArray(float32[5,4]),\n",
       "   _batch_axis=None,\n",
       "   axis_names=None\n",
       " ),\n",
       " 'Momentum3.b_v': Variable(\n",
       "   value=ShapedArray(float32[3,3]),\n",
       "   _batch_axis=None,\n",
       "   axis_names=None\n",
       " ),\n",
       " 'Constant10.last_epoch': Variable(\n",
       "   value=ShapedArray(int32[], weak_type=True),\n",
       "   _batch_axis=None,\n",
       "   axis_names=None\n",
       " )}"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 42
  },
  {
   "cell_type": "code",
   "id": "fb272a40",
   "metadata": {
    "scrolled": true,
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:03.737804Z",
     "start_time": "2025-10-06T05:15:03.721194Z"
    }
   },
   "source": [
    "bp.optim.Adam(lr=0.001, train_vars={'a': a, 'b': b}).vars()  # Adam has more variables"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Adam3.a_m': Variable(\n",
       "   value=ShapedArray(float32[5,4]),\n",
       "   _batch_axis=None,\n",
       "   axis_names=None\n",
       " ),\n",
       " 'Adam3.b_m': Variable(\n",
       "   value=ShapedArray(float32[3,3]),\n",
       "   _batch_axis=None,\n",
       "   axis_names=None\n",
       " ),\n",
       " 'Adam3.a_v': Variable(\n",
       "   value=ShapedArray(float32[5,4]),\n",
       "   _batch_axis=None,\n",
       "   axis_names=None\n",
       " ),\n",
       " 'Adam3.b_v': Variable(\n",
       "   value=ShapedArray(float32[3,3]),\n",
       "   _batch_axis=None,\n",
       "   axis_names=None\n",
       " ),\n",
       " 'Constant11.last_epoch': Variable(\n",
       "   value=ShapedArray(int32[], weak_type=True),\n",
       "   _batch_axis=None,\n",
       "   axis_names=None\n",
       " )}"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 43
  },
  {
   "cell_type": "markdown",
   "id": "8325c2b3-4354-4dfd-a0d2-b4f734832e12",
   "metadata": {},
   "source": [
    "BrainPy also supports learning rate modification of optimizer. For example, an optimizer ``opt = bp.optim.Adam(lr=0.1)`` is created, we want to change the value ``lr=0.1`` into ``lr=0.01``, we can use ``opt.lr.lr=0.01`` or ``opt.lr.set_value(0.01)`` to achieve the goal.\n",
    "Here is a complete example."
   ]
  },
  {
   "cell_type": "code",
   "id": "b09adff4-89b8-42c9-a7e9-3e608ad2c6f5",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:40.446023Z",
     "start_time": "2025-10-06T05:15:03.743444Z"
    }
   },
   "source": [
    "import brainpy as bp\n",
    "import brainpy.math as bm\n",
    "\n",
    "dt = 0.04\n",
    "num_step = int(1.0 / dt)\n",
    "num_batch = 128\n",
    "\n",
    "@bm.jit\n",
    "def build_inputs_and_targets(mean=0.025, scale=0.01):\n",
    "  sample = bm.random.normal(size=(num_batch, 1, 1))\n",
    "  bias = mean * 2.0 * (sample - 0.5)\n",
    "  samples = bm.random.normal(size=(num_batch, num_step, 1))\n",
    "  noise_t = scale / dt ** 0.5 * samples\n",
    "  inputs = bias + noise_t\n",
    "  targets = bm.cumsum(inputs, axis=1)\n",
    "  return inputs, targets\n",
    "\n",
    "def train_data():\n",
    "  for _ in range(100):\n",
    "    yield build_inputs_and_targets()\n",
    "\n",
    "class RNN(bp.DynamicalSystem):\n",
    "  def __init__(self, num_in, num_hidden):\n",
    "    super(RNN, self).__init__()\n",
    "    self.rnn = bp.dyn.RNNCell(num_in, num_hidden, train_state=True)\n",
    "    self.out = bp.dnn.Dense(num_hidden, 1)\n",
    "\n",
    "  def update(self, x):\n",
    "    return self.out(self.rnn(x))\n",
    "\n",
    "with bm.training_environment():\n",
    "    model = RNN(1, 100)\n",
    "\n",
    "def loss(predictions, targets, l2_reg=2e-4):\n",
    "    mse = bp.losses.mean_squared_error(predictions, targets)\n",
    "    l2 = l2_reg * bp.losses.l2_norm(model.train_vars().unique().dict()) ** 2\n",
    "    return mse + l2\n",
    "\n",
    "opt = bp.optim.Adam(lr=0.1)\n",
    "trainer = bp.BPTT(model, loss_fun=loss, optimizer=opt)\n",
    "opt.lr.lr=0.01        #Modify the learning rate. You can alse use \"opt.lr.set_value(0.01)\"\n",
    "trainer.fit(train_data, num_epoch=10)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train 0 epoch, use 4.0265 s, loss 5.584829807281494\n",
      "Train 1 epoch, use 3.4009 s, loss 0.04134882614016533\n",
      "Train 2 epoch, use 3.7700 s, loss 0.023480374366044998\n",
      "Train 3 epoch, use 3.3925 s, loss 0.0217495895922184\n",
      "Train 4 epoch, use 3.4066 s, loss 0.0214226134121418\n",
      "Train 5 epoch, use 3.7356 s, loss 0.021270286291837692\n",
      "Train 6 epoch, use 3.7256 s, loss 0.021091992035508156\n",
      "Train 7 epoch, use 3.4624 s, loss 0.020998552441596985\n",
      "Train 8 epoch, use 3.3258 s, loss 0.020898768678307533\n",
      "Train 9 epoch, use 3.5516 s, loss 0.020785270258784294\n"
     ]
    }
   ],
   "execution_count": 44
  },
  {
   "cell_type": "markdown",
   "id": "28a63538",
   "metadata": {},
   "source": [
    "## Creating A Self-Customized Optimizer"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9900e42",
   "metadata": {},
   "source": [
    "To create your own optimization algorithm, simply inherit from ``bp.optim.Optimizer`` class and override the following methods:\n",
    "\n",
    "- ``__init__()``: init function that receives the learning rate (``lr``) and trainable variables (``train_vars``). Do not forget to register your dynamical changed variables into ``implicit_vars``. \n",
    "- ``update(grads)``: update function that computes the updated parameters. \n",
    "\n",
    "The general structure is shown below:"
   ]
  },
  {
   "cell_type": "code",
   "id": "f3c84821",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:40.492833Z",
     "start_time": "2025-10-06T05:15:40.488749Z"
    }
   },
   "source": [
    "class CustomizeOp(bp.optim.Optimizer):\n",
    "    def __init__(self, lr, train_vars, *params, **other_params):\n",
    "        super(CustomizeOp, self).__init__(lr, train_vars)\n",
    "        \n",
    "        # customize your initialization\n",
    "        \n",
    "    def update(self, grads):\n",
    "        # customize your update logic\n",
    "        pass"
   ],
   "outputs": [],
   "execution_count": 45
  },
  {
   "cell_type": "markdown",
   "id": "f5b91a31",
   "metadata": {},
   "source": [
    "## Schedulers"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2c277e6",
   "metadata": {},
   "source": [
    "Scheduler seeks to adjust the learning rate during training through reducing the learning rate according to a pre-defined schedule.  Common learning rate schedules include time-based decay, step decay and exponential decay. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e2c504d7",
   "metadata": {},
   "source": [
    "Here we set up an exponential decay scheduler, in which the learning rate will decay exponentially along the training step."
   ]
  },
  {
   "cell_type": "code",
   "id": "75476a94",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:40.526885Z",
     "start_time": "2025-10-06T05:15:40.503255Z"
    }
   },
   "source": [
    "sc = bp.optim.ExponentialDecayLR(lr=0.1, decay_steps=2, decay_rate=0.99)"
   ],
   "outputs": [],
   "execution_count": 46
  },
  {
   "cell_type": "code",
   "id": "fe673807",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:40.534984Z",
     "start_time": "2025-10-06T05:15:40.530546Z"
    }
   },
   "source": [
    "def show(steps, rates):\n",
    "    plt.plot(steps, rates)\n",
    "    plt.xlabel('Train Step')\n",
    "    plt.ylabel('Learning Rate')\n",
    "    plt.show()"
   ],
   "outputs": [],
   "execution_count": 47
  },
  {
   "cell_type": "code",
   "id": "8c0b8a9c",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:40.759965Z",
     "start_time": "2025-10-06T05:15:40.548977Z"
    }
   },
   "source": [
    "steps = bm.arange(1000)\n",
    "rates = sc(steps)\n",
    "\n",
    "show(steps, rates)"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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gIioTUgkkls+3nzzzTva77Fjx/D88883q7aMjAz89a9/haenJ5RKJby8vDBu3DikpqYCADIzMyGRSHDixIlmfQ4RWQ6Z2AUQkXXIzc01/r5p0yYsWrTIZDV0R0dH4++CIECv10Mmu/2fqC5dujSrrtraWjzwwAPo06cPtmzZgq5du+Ly5cvYtWsXSkpKmrVvIrJc7AEiojahVquND5VKBYlEYnyempoKJycn7Nq1CyEhIVAoFDh06BAuXryIcePGwcPDA46OjggNDcWvv/5qst8/XwKTSCT4/PPPMWHCBNjb28PPzw/bt2+/aV1nzpzBxYsXsXr1agwZMgQ9evTAPffcgyVLlmDIkCEAAF9fXwDAwIEDIZFIcN999xnf//nnnyMgIABKpRL+/v5YvXq18bWGnqONGzdi6NChUCqVCAwMxP79+1vgjBJRczAAEZHFmDdvHpYuXYqUlBT0798f5eXlGD16NGJjY5GUlISHHnoIY8eORVZW1i3389Zbb+HJJ5/EqVOnMHr0aEyePBnFxcWNtu3SpQukUil+/PFH6PX6RtvEx8cDAH799Vfk5uZiy5YtAIDvvvsOixYtwrvvvouUlBT861//wsKFC7F+/XqT98+dOxdz5sxBUlISwsPDMXbsWBQVFZl7eoioJbXImvJERGb46quvBJVKZXy+d+9eAYCwbdu22763X79+wscff2x83qNHD+E///mP8TkA4Y033jA+Ly8vFwAIu3btuuk+V65cKdjb2wtOTk7C/fffL7z99tvCxYsXja9nZGQIAISkpCST9911113Chg0bTLa98847Qnh4uMn7li5dany9trZW8PLyEt57773bHisRtR72ABGRxRg0aJDJ8/Lycrz66qsICAiAi4sLHB0dkZKSctseoP79+xt/d3BwgLOzM/Lz82/afvr06dBoNPjuu+8QHh6OzZs3o1+/ftizZ89N31NRUYGLFy9i2rRpcHR0ND6WLFmCixcvmrQNDw83/i6TyTBo0CCkpKTc8hiIqHVxEDQRWQwHBweT56+++ir27NmDDz74AL169YKdnR0ef/xx6HS6W+7H1tbW5LlEIoHBYLjle5ycnDB27FiMHTsWS5YsQWRkJJYsWYIHHnig0fbl5eUAgLVr1yIsLMzkNRsbm1t+FhGJjz1ARGSxfv/9dzzzzDOYMGECgoKCoFarkZmZ2eqfK5FI4O/vj4qKCgCAXC4HAJMxQh4eHvD09ER6ejp69epl8mgYNN3gyJEjxt/r6uqQmJiIgICAVj8OIro59gARkcXy8/PDli1bMHbsWEgkEixcuPC2PTnmOnHiBBYvXoynn34affv2hVwux/79+/Hll1/itddeAwC4u7vDzs4OMTEx8PLyglKphEqlwltvvYWZM2dCpVLhoYceQk1NDRISEnD16lVERUUZP2PVqlXw8/NDQEAA/vOf/+Dq1at47rnnWvQ4iMg8DEBEZLH+/e9/47nnnsPQoUPh5uaG1157DVqttkU/w8vLCz4+PnjrrbeMt603PH/llVcA1I/bWbFiBd5++20sWrQIw4cPx759+/C3v/0N9vb2eP/99zF37lw4ODggKCgIs2fPNvmMpUuXYunSpThx4gR69eqF7du3w83NrUWPg4jMIxEEQRC7CCKijigzMxO+vr5ISkpCcHCw2OUQ0XU4BoiIiIisDgMQERERWR1eAiMiIiKrwx4gIiIisjoMQERERGR1GICIiIjI6jAAERERkdVhACIiIiKrwwBEREREVocBiIiIiKwOAxARERFZnf8HMApgss1eQm0AAAAASUVORK5CYII="
     },
     "metadata": {},
     "output_type": "display_data",
     "jetTransient": {
      "display_id": null
     }
    }
   ],
   "execution_count": 48
  },
  {
   "cell_type": "markdown",
   "id": "2958e220",
   "metadata": {},
   "source": [
    "After Optimizer initialization, the learning rate ``self.lr`` will always be an instance of ``bm.optimizers.Scheduler``. A scalar float learning rate initialization will result in a ``Constant`` scheduler. "
   ]
  },
  {
   "cell_type": "code",
   "id": "d67a3c6e",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:40.807673Z",
     "start_time": "2025-10-06T05:15:40.802536Z"
    }
   },
   "source": [
    "op.lr"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Constant(lr=0.001, last_epoch=-1)"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 49
  },
  {
   "cell_type": "markdown",
   "id": "83340b85",
   "metadata": {},
   "source": [
    "One can get the current learning rate value by calling ``Scheduler.__call__(i=None)``.\n",
    "\n",
    "- If `i` is not provided, the learning rate value will be evaluated at the built-in training ``step``.\n",
    "- Otherwise, the learning rate value will be evaluated at the given step ``i``. "
   ]
  },
  {
   "cell_type": "code",
   "id": "7b5dd012",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:40.827889Z",
     "start_time": "2025-10-06T05:15:40.823688Z"
    }
   },
   "source": [
    "op.lr()"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.001"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 50
  },
  {
   "cell_type": "markdown",
   "id": "029e39db",
   "metadata": {},
   "source": [
    "In BrainPy, several commonly used learning rate schedulers are used:\n",
    "\n",
    "- Constant\n",
    "- StepLR\n",
    "- MultiStepLR\n",
    "- CosineAnnealingLR\n",
    "- ExponentialLR\n",
    "- ExponentialDecayLR\n",
    "- InverseTimeDecayLR\n",
    "- PolynomialDecayLR\n",
    "- PiecewiseConstantLR\n",
    "- CosineAnnealingWarmRestarts\n",
    "\n",
    "For more details, please see the [brainpy.math.optimizers APIs](../apis/auto/math/optimizers.rst). \n"
   ]
  },
  {
   "cell_type": "code",
   "id": "f5da4916",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:41.032837Z",
     "start_time": "2025-10-06T05:15:40.833291Z"
    }
   },
   "source": [
    "# InverseTimeDecay scheduler\n",
    "\n",
    "rates = bp.optim.InverseTimeDecayLR(lr=0.01, decay_steps=10, decay_rate=0.999)(steps)\n",
    "show(steps, rates)"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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cAYn3skGAAACq9kBqd4XX3yhwsJCVVf792hce+21P7gonKx+LqQyepAAAAi4ZgekHTt26Prrr9dnn33mG3skyTc3D2OQAoMeJAAAgqfZt/lPmjRJycnJ2rdvnyIjI/X555/ro48+Umpqqv7xj38EoERIx+dCYgwSAACB1+wepPz8fK1evVpxcXGyWq2yWq0aPny4cnJydM899zBHUoC0r+tB4i42AAACr9k9SG63W9HR0ZKkuLg47dmzR5J38Pb27dtbtjr41PcgldKDBABAwDW7B6lv37769NNPlZycrLS0NM2dO1fh4eFavHixzjvvvEDUCB0fg0QPEgAAgdfsHqQZM2bI4/FIkh555BEVFBTo0ksv1TvvvKP58+efVRELFy5Uz5495XQ6lZaWpnXr1p22/fLly9W7d285nU7169dP77zzjt96wzCUnZ2tLl26KCIiQhkZGfr6668b3VdVVZUGDBggi8WiLVu2nFX9wdCeMUgAAARNswNSZmambrjhBklSr169tG3bNpWUlGjfvn36yU9+0uwC3njjDU2ZMkWzZs3Spk2b1L9/f2VmZmrfvn2Ntl+zZo1uueUWTZgwQZs3b1ZWVpaysrK0detWX5u5c+dq/vz5WrRokdauXat27dopMzNTx44dO2l/06ZNU2JiYrPrDrb6MUhlR2vk8RgmVwMAwLmt2QGp3jfffKP33ntPR48eVYcOHc66gKefflq33367xo8frwsvvFCLFi1SZGSk/vjHPzba/tlnn9WVV16p+++/X3369NGjjz6qH//4x1qwYIEkb+/RvHnzNGPGDF133XW6+OKL9dprr2nPnj1auXKl377effdd/d///Z+efPLJs64/WFx1AcljSBXHak2uBgCAc1uzA9KBAwd0xRVX6Ec/+pGuvvpq7d27V5I0YcIETZ06tVn7qq6u1saNG5WRkXG8IKtVGRkZys/Pb3Sb/Px8v/aSt1ervn1BQYGKior82rhcLqWlpfnts7i4WLfffrv+9Kc/KTIy8oy1VlVVqby83O8VTA67Te3CbZKkg1xmAwAgoJodkO69916FhYWpsLDQL1iMHj1aubm5zdpXSUmJ3G634uPj/ZbHx8erqKio0W2KiopO277+5+naGIah2267TXfccYdSU1ObVGtOTo5cLpfvlZSU1KTtWlJctEOSVHK4KujfDQBAW9LsgPR///d/evzxx9WtWze/5SkpKfruu+9arLBAeu6551RRUaEHH3ywyds8+OCDKisr87127doVwAob1ynKG5D2VxCQAAAIpGYHpMrKykYvSR08eFAOh6NZ+4qLi5PNZlNxcbHf8uLiYiUkJDS6TUJCwmnb1/88XZvVq1crPz9fDodDdrtdvXr1kiSlpqZq3LhxjX6vw+FQTEyM3yvYOkUTkAAACIZmB6RLL71Ur732mu+zxWKRx+PR3LlzdfnllzdrX+Hh4Ro0aJDy8vJ8yzwej/Ly8pSent7oNunp6X7tJWnVqlW+9snJyUpISPBrU15errVr1/razJ8/X59++qm2bNmiLVu2+KYJeOONN/TYY4816xiCiYAEAEBwNHuiyLlz5+qKK67Qhg0bVF1drWnTpunzzz/XwYMH9a9//avZBUyZMkXjxo1TamqqhgwZonnz5qmyslLjx4+XJI0dO1Zdu3ZVTk6OJO+z4EaMGKGnnnpKI0eO1LJly7RhwwYtXrxYkjewTZ48WbNnz1ZKSoqSk5M1c+ZMJSYmKisrS5LUvXt3vxqioqIkSeeff/5Jlw5DSRyX2AAACIqzmkn7q6++0oIFCxQdHa3Dhw/rhhtu0J133qkuXbo0u4DRo0dr//79ys7OVlFRkQYMGKDc3FzfIOvCwkJZrcc7uoYNG6alS5dqxowZmj59ulJSUrRy5Ur17dvX12batGmqrKzUxIkTVVpaquHDhys3N1dOp7PZ9YWSTgzSBgAgKCyGYbTIrIPff/+9HnnkEV9PzrmuvLxcLpdLZWVlQRuP9P4Xxfqv1zbo4m4uvXnX8KB8JwAA55Km/v0+64kiGzpw4IBefvnlltodGsEYJAAAgqPFAhIC78RLbDxuBACAwCEgtSIdo7wPrK1xGyo7WmNyNQAAnLsISK2Iw26TK8L7TLb9DNQGACBgmnwX2w033HDa9aWlpT+0FjRBp2iHyo7WqKSiSj+Kjza7HAAAzklNDkgul+uM68eOHfuDC8LpdYpy6Jt9h+lBAgAggJockF555ZVA1oEmqh+ova+cgAQAQKAwBqmViY/xBqTi8mMmVwIAwLmLgNTKdHFFSJL2lB01uRIAAM5dBKRWJjG2LiCV0oMEAECgEJBamcRY7/Pk9pTSgwQAQKAQkFqZ+h6k/YerVF3rMbkaAADOTQSkVqZju3CF260yDAZqAwAQKASkVsZisSjR5b3MtpvLbAAABAQBqRWqv8y2lzvZAAAICAJSK+S71Z872QAACAgCUivUlTvZAAAIKAJSK3R8LiQCEgAAgUBAaoW6MFkkAAABRUBqhbp3iJQkFR48IsMwTK4GAIBzDwGpFeoaGyGb1aKjNW7tr6gyuxwAAM45BKRWKNxu9T1yZOeBIyZXAwDAuYeA1Er17NhOkrTzQKXJlQAAcO4hILVSPTp6xyF9R0ACAKDFEZBaqeM9SFxiAwCgpRGQWqkedQGJHiQAAFoeAamV6ll/ia2EW/0BAGhpBKRWKqluLqSKqlodrKw2uRoAAM4tBKRWyhlmU6LLe6t/QQmX2QAAaEkEpFbs/M5RkqSv9x02uRIAAM4tBKRW7Efx0ZKkr4orTK4EAIBzCwGpFftRfF0PUjE9SAAAtCQCUiuWQg8SAAABQUBqxVLqxiDtq6hS2ZEak6sBAODcQUBqxaKdYepSdyfb1/voRQIAoKUQkFq545fZGIcEAEBLISC1chfUDdTeXlRuciUAAJw7CEit3IWJMZKkz/cQkAAAaCkEpFauX1eXJG9Acnt4JhsAAC2BgNTKJcdFKSLMpqM1bhWUMA4JAICWQEBq5WxWi+8y29bdXGYDAKAlEJDOAfWX2T7bXWZyJQAAnBsISOeAi3w9SAQkAABaAgHpHNCvm7cHaevuMgZqAwDQAghI54CUztGKcthVWe3WNuZDAgDgByMgnQNsVosGdo+VJG367pC5xQAAcA4gIJ0jBvVoL0naQEACAOAHIyCdI1J7dJAkbdhJQAIA4IciIJ0jBnSPldUi7S49qqKyY2aXAwBAq0ZAOkdEOezq08V7u//aggMmVwMAQOtGQDqHDDu/oyRpzTcEJAAAfggC0jlkWK84SdK/vi0xuRIAAFo3AtI5ZEjPDrJbLfr+0FEVHjhidjkAALRaBKRzSDuHXT/u7r3d/+Nv6EUCAOBsEZDOMZfUXWb76Kv9JlcCAEDrRUA6x/ykd2dJ0kdf79exGrfJ1QAA0DoRkM4xfbvGKD7GoSPVbuXv4G42AADORkgEpIULF6pnz55yOp1KS0vTunXrTtt++fLl6t27t5xOp/r166d33nnHb71hGMrOzlaXLl0UERGhjIwMff311771O3fu1IQJE5ScnKyIiAidf/75mjVrlqqrqwNyfMFksViU0SdekvT+F8UmVwMAQOtkekB64403NGXKFM2aNUubNm1S//79lZmZqX379jXafs2aNbrllls0YcIEbd68WVlZWcrKytLWrVt9bebOnav58+dr0aJFWrt2rdq1a6fMzEwdO+adYXrbtm3yeDx64YUX9Pnnn+uZZ57RokWLNH369KAcc6D99MK6gPRlsTwew+RqAABofSyGYZj6FzQtLU2DBw/WggULJEkej0dJSUm6++679cADD5zUfvTo0aqsrNTbb7/tWzZ06FANGDBAixYtkmEYSkxM1NSpU3XfffdJksrKyhQfH68lS5bo5ptvbrSOJ554Qn/4wx+0Y8eORtdXVVWpqqrK97m8vFxJSUkqKytTTEzMWR9/IFTVuvXjR1apstqtN++6RBd3izW7JAAAQkJ5eblcLtcZ/36b2oNUXV2tjRs3KiMjw7fMarUqIyND+fn5jW6Tn5/v116SMjMzfe0LCgpUVFTk18blciktLe2U+5S8IapDhw6nXJ+TkyOXy+V7JSUlNekYzeCw2zTigk6SpP/9916TqwEAoPUxNSCVlJTI7XYrPj7eb3l8fLyKiooa3aaoqOi07et/Nmef33zzjZ577jn96le/OmWtDz74oMrKynyvXbt2nf7gTHZt/0RJ0puf7uEyGwAAzWQ3uwCz7d69W1deeaVuuukm3X777ads53A45HA4gljZD3PZBZ0V7bRrb9kxrS04qPS657QBAIAzM7UHKS4uTjabTcXF/ndbFRcXKyEhodFtEhISTtu+/mdT9rlnzx5dfvnlGjZsmBYvXvyDjiXUOMNsGtmviyRp5ebdJlcDAEDrYmpACg8P16BBg5SXl+db5vF4lJeXp/T09Ea3SU9P92svSatWrfK1T05OVkJCgl+b8vJyrV271m+fu3fv1mWXXaZBgwbplVdekdVq+g19LS5rYFdJ0juf7WXSSAAAmsH0S2xTpkzRuHHjlJqaqiFDhmjevHmqrKzU+PHjJUljx45V165dlZOTI0maNGmSRowYoaeeekojR47UsmXLtGHDBl8PkMVi0eTJkzV79mylpKQoOTlZM2fOVGJiorKysiQdD0c9evTQk08+qf37jz+W41Q9V63RkJ4d1DU2QrtLj+rdrXt1/cBuZpcEAECrYHpAGj16tPbv36/s7GwVFRVpwIABys3N9Q2yLiws9OvdGTZsmJYuXaoZM2Zo+vTpSklJ0cqVK9W3b19fm2nTpqmyslITJ05UaWmphg8frtzcXDmdTkneHqdvvvlG33zzjbp18w8NJs960KKsVotGD07S06u+0p/yvyMgAQDQRKbPg9RaNXUeBbPtqzimS+asVo3b0Nt3D1ffri6zSwIAwDStYh4kBF7naKeu7OsdrP3fn3xncjUAALQOBKQ24NahPSRJK7fs1oHDVWdoDQAACEhtwOCe7dWvq0vHajxasman2eUAABDyCEhtgMVi0Z2Xny9JWrJmpyqO1ZhcEQAAoY2A1Eb87MIE9eocpYpjtfoTY5EAADgtAlIbYbVa9JvLvL1IL360Q+X0IgEAcEoEpDbk2v6JOr9TOx06UqMXPvzW7HIAAAhZBKQ2xG6zatqVvSVJL39coKKyYyZXBABAaCIgtTE/uzBeqT3a61iNR3Pf22Z2OQAAhCQCUhtjsVj00Mg+slikFZt2K//bA2aXBABAyCEgtUEDu7fXL4Z0lyQ9tPIzVdW6Ta4IAIDQQkBqo6Zd2VtxUQ7t2F+pRf/YYXY5AACEFAJSG+WKCFP2qAslSQs++FqffV9mckUAAIQOAlIbNuriLrryogTVuA3ds2yzKqtqzS4JAICQQEBqwywWi+bc2E8JMU4VlFTq4bc+N7skAABCAgGpjYuNDNczowfIYpH+suF7/WX9LrNLAgDAdAQkKP38jpp0RYok711tG787aHJFAACYi4AESdI9P0nRVX2945F+9adN2l161OySAAAwDQEJkrwPs33ypv7qnRCtksNVuvXltTpwuMrssgAAMAUBCT7tHHb98bbBSnQ5tWN/pW57Zb0qjtWYXRYAAEFHQIKfxNgI/em/0tShXbg+212m215Zr7KjhCQAQNtCQMJJzu8UpVfHD1GM066N3x3SL178hMttAIA2hYCERvXr5tKyienq2C5cn+8p1+jFn2gPA7cBAG0EAQmndGFijP5yR7q6uJz6Zt9hXbvgX9pceMjssgAACDgCEk7r/E5R+uuvh/nubhu9+BOt3Lzb7LIAAAgoAhLOqGtshP7n18OU0Sde1bUeTX5jix5c8ZmOVrvNLg0AgIAgIKFJ2jnsWnzrIN11eS9ZLNKf1xXquoUfa3tRhdmlAQDQ4ghIaDKr1aL7Mi/Qf09IU6doh74qPqxRCz7Wwg++UY3bY3Z5AAC0GAISmu2SXnF6d9KluuyCTqqu9eiJ97br2gX/0r+/LzW7NAAAWgQBCWclLsqhV24brKdu6q/YyDB9ubdcWQv/pQdXfKb9FcyZBABo3QhIOGsWi0U3Duqm96eM0HUDEuUxvGOTLnviAy1Y/bWO1TCIGwDQOlkMwzDMLqI1Ki8vl8vlUllZmWJiYswuJySs33lQs9/+Qp9+XyZJio9x6Ff/cb5+kdZdzjCbydUBAND0v98EpLNEQGqcx2PozU/36In3tmt33czbcVEOTfyPZP0irYeiHHaTKwQAtGUEpAAjIJ1eVa1bf934vZ7/4FtfUIp22PXz1G4al95TPePamVwhAKAtIiAFGAGpaWrcHv1t024t+vBb7SiplCRZLNLlF3TWL4Z014gLOinMxlA4AEBwEJACjIDUPB6PoX9+U6Il/yrQB9v3+5bHRYUra0BX3Tiom/p04TwCAAKLgBRgBKSzV1BSqdc/+U4rt+xWyeFq3/I+XWI0sl+CruzbRb06R5lYIQDgXEVACjAC0g9X4/boo6/2668bv9f7Xxarxn38P8VenaN0Vd8EZV6UoIsSY2SxWEysFABwriAgBRgBqWUdqqzW/31RpHe3Fulf35T4haVO0Q5dmhKnET/qpEtTOqlDu3ATKwUAtGYEpAAjIAVO2dEard5WrHc/K9LH35ToSPXxCSctFuniri6lnx+nIcntNahHB7kiwkysFgDQmhCQAoyAFBxVtW5t3HlIH361Xx9+tV/biir81lssUp+EGA1J7qAhyR00IClWXVxOLskBABpFQAowApI5isqO6eNvSrS+4KDW7TyogrqpA04UF+VQ/24uXdwtVhcnudS/WyyX5QAAkghIAUdACg37yo9p3c6DWldwUBt2HtL24gq5PSf/J92tfYR6J0TrgoRo9U6IUe+EaCXHtZOdOZgAoE0hIAUYASk0Hatx6/M95fp0V6n+/X2p/v19mW+CyobCbVad3zlKfRKi1Ss+SufFtVNyXJR6dIzk2XEAcI4iIAUYAan1KDtaoy/3lmvb3nJtL67QtqIKfVVUocoTBn+fyGKRusZGKDmuXV1oaqfkTlFKah+hru0j5LATngCgtSIgBRgBqXXzeAztLj2qbUUV2ra3XDtKKr2v/YdVcaz2tNvGxzjUrX2kurWPULf2EUpqH+n73CXWSYACgBBGQAowAtK5yTAMHais1o79lSooOVwXmiq1s6RS3x86qqM1jfc6nSguKlydo51KcDkVH+NUQoxTCS6HOte/j3EqNjKMO+0AwARN/fttD2JNQMizWCyKi3IoLsqhIckd/NYZhqGDldX6/tDRutcRfX/oqHbV/fz+0BEdq/Go5HC1Sg5X64u95af8HofdqvgYp+KiwtWx7vviosLVsZ33c8eocHWKcqhjlEOxEWGyWglTABBMBCSgiSwWS114cah/UuxJ6+sDVFH5MRWXH1NxeZWKyrzvi8qPqajsmPZVVOlgZbWqaj0qPHhEhQePnPF7rRapQztvgOrQLlztI8PligxT+8gwxUZ438dGhCk2MlztI8PqPocr3M4degBwtghIQAs5MUBdlOg6ZbuqWrf2lVepqPyYDhyuUsnhah04XK0DlVUq8X2u0oHKapUeqZHHUN3yqmbVExlu8wWn2MgwuSLCFO20K9oZpiiHXdFOu2KcJyxz2uvee5c77FYuAwJoswhIQJA57DYldYhUUofIM7atcXt0sLJaJYerfCGq7EiNSo/WqPRIjUqPVPvelx31fi476g1VR6rdOlLt1p6yY2dVZ5jN4hem6oNUu3CbIh12789wuyIbfG7nOP6zXd36dg47gQtAq0JAAkJYmM07Vik+xtnkbTweQxXHalV61NsDVXpCcKo4Vlv3qmnws+59Va0OV9XKMKQat/eS4cHK6hY5FqtF3sDkOB6s2oXb5Qy3KSLMKmeYTRFhNjnDbHKEWX3vvT+9609sc9LycJucdiuTfwJoEQQk4BxjtVrkqhuL1KNj87f3eAxVVteeHKaqvO+PVrtVWeXWkepaVVbX6kiV2/uz2q3Kqlpfz9WR6lpVVrl9d/55DHn3UVUrqXmXC5sjzGaR026TM9wboBx2m8JtVjnCrHU/j392nLA83F7X1m6Vw9745/r3jtO0DbdZFWaz0FsGtHIEJAB+rFbvpbVoZ1iL7M/tMXS0xq0jVbWqPCFE1YerYzXeEHXM9/L4Ph+tcauqwedjNR5f26MnbFOvxm2oxl0fxMwTZrMozGaV3WpRuN2qMJv3ZbdZ6kKUN0jZbcdD1YnvvW2tCq97H2a3Ksx6/H3D/dZvc+J32K3efXp/WmS3WmWzWhRms8hm9X72Lj/ezrucgAcQkAAElM1qUZTDrihH4P65MQxDVbUeHa1261it2/uzLlhV13pU7faoqsZd97Pxz9W1HlX5Xm7f5+oTPvtv77+fGrf/lHLeoHbmebNCla0uLIXVh6b6oGW1yGazKKwubJ0YrBoLXv7bWk/Y3iJbg3Y2q0U2i0XWE4Ka1eJ9b63/bt96yWa1ymbxvrdavCGwvr3Ncnyf1gafbXX7tZ9qvcUiq1WyW62yWuVbR2hsWwhIAFo9i8XiG4tkFo/H8AWnGo9HNW6Pat1GXXjyqKbW8C6v9dSFp7rlde+r69rXLz/xc3Xd9rV1+62u9S6v9Rx/f9L31e3b7TFU6/ao1mN4X26P3B5DNR7vusYe7izJt65lRqCdG6wW+cKVrZFQZ2+w7sT21rrQ5Xtft85i8W9nsVhks+j4+/ptrCdsZ/Hfzq/dCfs/cZvj+5CvXkv9e0vde+vJ29rq1tUf14nvrRbV1dvw2Pw/26yqq/d4LfX7qV9msTTeJi7KYdr/1wQkAGgBVqtFTqu5Ie1sGIY3OLlPCFD1n2vqw1R90PJ4Q5ivfWNtPYbcJ7Sr9RhynxDQTmx74vfVug25DUOe+uBW977WY8hj1Ic5ye3xyG3Ir119mPOc8P6kffjaSh7D+70eQyft43Q8huRxG5J4AEWwvPbLIfqPH3Uy5btDIiAtXLhQTzzxhIqKitS/f38999xzGjJkyCnbL1++XDNnztTOnTuVkpKixx9/XFdffbVvvWEYmjVrll588UWVlpbqkksu0R/+8AelpKT42hw8eFB333233nrrLVmtVt1444169tlnFRUVFdBjBYBQYrFY6sYvmV1JaPA0CEx+oe2EdR6PVOvx1IUynbze8IY+Q962HsO7zjC8n33v60KaxzBknPDeU7fOU/f99e/dHm+74/s7cRvVtW18W4+vNu/fSb/3J23jPS6jfjvjhPeN7MNXs0f+9dfvq65Ww/BfbzT43uPrvT9tJj5FwPSA9MYbb2jKlClatGiR0tLSNG/ePGVmZmr79u3q3LnzSe3XrFmjW265RTk5Obrmmmu0dOlSZWVladOmTerbt68kae7cuZo/f75effVVJScna+bMmcrMzNQXX3whp9N7u/SYMWO0d+9erVq1SjU1NRo/frwmTpyopUuXBvX4AQChw2q1yCoCI0LgYbVpaWkaPHiwFixYIEnyeDxKSkrS3XffrQceeOCk9qNHj1ZlZaXefvtt37KhQ4dqwIABWrRokQzDUGJioqZOnar77rtPklRWVqb4+HgtWbJEN998s7788ktdeOGFWr9+vVJTUyVJubm5uvrqq/X9998rMTHxpO+tqqpSVdXxW5PLy8uVlJTEw2oBAGhFmvqwWlNnVKuurtbGjRuVkZHhW2a1WpWRkaH8/PxGt8nPz/drL0mZmZm+9gUFBSoqKvJr43K5lJaW5muTn5+v2NhYXziSpIyMDFmtVq1du7bR783JyZHL5fK9kpKSzu6gAQBAyDM1IJWUlMjtdis+Pt5veXx8vIqKihrdpqio6LTt63+eqU3Dy3d2u10dOnQ45fc++OCDKisr87127drVxKMEAACtjeljkFoLh8Mhh8NhdhkAACAITO1BiouLk81mU3Fxsd/y4uJiJSQkNLpNQkLCadvX/zxTm3379vmtr62t1cGDB0/5vQAAoO0wNSCFh4dr0KBBysvL8y3zeDzKy8tTenp6o9ukp6f7tZekVatW+donJycrISHBr015ebnWrl3ra5Oenq7S0lJt3LjR12b16tXyeDxKS0trseMDAACtk+mX2KZMmaJx48YpNTVVQ4YM0bx581RZWanx48dLksaOHauuXbsqJydHkjRp0iSNGDFCTz31lEaOHKlly5Zpw4YNWrx4sSTvnB6TJ0/W7NmzlZKS4rvNPzExUVlZWZKkPn366Morr9Ttt9+uRYsWqaamRnfddZduvvnmRu9gAwAAbYvpAWn06NHav3+/srOzVVRUpAEDBig3N9c3yLqwsFBW6/GOrmHDhmnp0qWaMWOGpk+frpSUFK1cudI3B5IkTZs2TZWVlZo4caJKS0s1fPhw5ebm+uZAkqTXX39dd911l6644grfRJHz588P3oEDAICQZfo8SK1VU+dRAAAAoaNVzIMEAAAQighIAAAADRCQAAAAGiAgAQAANEBAAgAAaMD02/xbq/qb/8rLy02uBAAANFX93+0z3cRPQDpLFRUVkqSkpCSTKwEAAM1VUVEhl8t1yvXMg3SWPB6P9uzZo+joaFkslhbbb3l5uZKSkrRr1y7mVwowznVwcJ6Dg/McHJzn4AnUuTYMQxUVFUpMTPSbiLohepDOktVqVbdu3QK2/5iYGP7nCxLOdXBwnoOD8xwcnOfgCcS5Pl3PUT0GaQMAADRAQAIAAGiAgBRiHA6HZs2aJYfDYXYp5zzOdXBwnoOD8xwcnOfgMftcM0gbAACgAXqQAAAAGiAgAQAANEBAAgAAaICABAAA0AABKcQsXLhQPXv2lNPpVFpamtatW2d2Sa1GTk6OBg8erOjoaHXu3FlZWVnavn27X5tjx47pzjvvVMeOHRUVFaUbb7xRxcXFfm0KCws1cuRIRUZGqnPnzrr//vtVW1sbzENpVebMmSOLxaLJkyf7lnGeW87u3bv1//7f/1PHjh0VERGhfv36acOGDb71hmEoOztbXbp0UUREhDIyMvT111/77ePgwYMaM2aMYmJiFBsbqwkTJujw4cPBPpSQ5Xa7NXPmTCUnJysiIkLnn3++Hn30Ub9ndXGez85HH32kUaNGKTExURaLRStXrvRb31Ln9d///rcuvfRSOZ1OJSUlae7cuT+8eAMhY9myZUZ4eLjxxz/+0fj888+N22+/3YiNjTWKi4vNLq1VyMzMNF555RVj69atxpYtW4yrr77a6N69u3H48GFfmzvuuMNISkoy8vLyjA0bNhhDhw41hg0b5ltfW1tr9O3b18jIyDA2b95svPPOO0ZcXJzx4IMPmnFIIW/dunVGz549jYsvvtiYNGmSbznnuWUcPHjQ6NGjh3HbbbcZa9euNXbs2GG89957xjfffONrM2fOHMPlchkrV640Pv30U+Paa681kpOTjaNHj/raXHnllUb//v2NTz75xPjnP/9p9OrVy7jlllvMOKSQ9NhjjxkdO3Y03n77baOgoMBYvny5ERUVZTz77LO+Npzns/POO+8YDz30kLFixQpDkvG3v/3Nb31LnNeysjIjPj7eGDNmjLF161bjz3/+sxEREWG88MILP6h2AlIIGTJkiHHnnXf6PrvdbiMxMdHIyckxsarWa9++fYYk48MPPzQMwzBKS0uNsLAwY/ny5b42X375pSHJyM/PNwzD+z+z1Wo1ioqKfG3+8Ic/GDExMUZVVVVwDyDEVVRUGCkpKcaqVauMESNG+AIS57nl/Pa3vzWGDx9+yvUej8dISEgwnnjiCd+y0tJSw+FwGH/+858NwzCML774wpBkrF+/3tfm3XffNSwWi7F79+7AFd+KjBw50vjlL3/pt+yGG24wxowZYxgG57mlNAxILXVen3/+eaN9+/Z+/3b89re/NS644IIfVC+X2EJEdXW1Nm7cqIyMDN8yq9WqjIwM5efnm1hZ61VWViZJ6tChgyRp48aNqqmp8TvHvXv3Vvfu3X3nOD8/X/369VN8fLyvTWZmpsrLy/X5558HsfrQd+edd2rkyJF+51PiPLekN998U6mpqbrpppvUuXNnDRw4UC+++KJvfUFBgYqKivzOtcvlUlpamt+5jo2NVWpqqq9NRkaGrFar1q5dG7yDCWHDhg1TXl6evvrqK0nSp59+qo8//lhXXXWVJM5zoLTUec3Pz9d//Md/KDw83NcmMzNT27dv16FDh866Ph5WGyJKSkrkdrv9/mBIUnx8vLZt22ZSVa2Xx+PR5MmTdckll6hv376SpKKiIoWHhys2NtavbXx8vIqKinxtGvsd1K+D17Jly7Rp0yatX7/+pHWc55azY8cO/eEPf9CUKVM0ffp0rV+/Xvfcc4/Cw8M1btw437lq7FyeeK47d+7st95ut6tDhw6c6zoPPPCAysvL1bt3b9lsNrndbj322GMaM2aMJHGeA6SlzmtRUZGSk5NP2kf9uvbt259VfQQknJPuvPNObd26VR9//LHZpZxzdu3apUmTJmnVqlVyOp1ml3NO83g8Sk1N1e9//3tJ0sCBA7V161YtWrRI48aNM7m6c8df/vIXvf7661q6dKkuuugibdmyRZMnT1ZiYiLnuQ3jEluIiIuLk81mO+lOn+LiYiUkJJhUVet011136e2339YHH3ygbt26+ZYnJCSourpapaWlfu1PPMcJCQmN/g7q18F7CW3fvn368Y9/LLvdLrvdrg8//FDz58+X3W5XfHw857mFdOnSRRdeeKHfsj59+qiwsFDS8XN1un83EhIStG/fPr/1tbW1OnjwIOe6zv33368HHnhAN998s/r166dbb71V9957r3JyciRxngOlpc5roP49ISCFiPDwcA0aNEh5eXm+ZR6PR3l5eUpPTzexstbDMAzddddd+tvf/qbVq1ef1OU6aNAghYWF+Z3j7du3q7Cw0HeO09PT9dlnn/n9D7lq1SrFxMSc9Ieqrbriiiv02WefacuWLb5XamqqxowZ43vPeW4Zl1xyyUlTVXz11Vfq0aOHJCk5OVkJCQl+57q8vFxr1671O9elpaXauHGjr83q1avl8XiUlpYWhKMIfUeOHJHV6v/n0GazyePxSOI8B0pLndf09HR99NFHqqmp8bVZtWqVLrjggrO+vCaJ2/xDybJlywyHw2EsWbLE+OKLL4yJEycasbGxfnf64NR+/etfGy6Xy/jHP/5h7N271/c6cuSIr80dd9xhdO/e3Vi9erWxYcMGIz093UhPT/etr7/9/Gc/+5mxZcsWIzc31+jUqRO3n5/BiXexGQbnuaWsW7fOsNvtxmOPPWZ8/fXXxuuvv25ERkYa//3f/+1rM2fOHCM2Ntb4+9//bvz73/82rrvuukZvkx44cKCxdu1a4+OPPzZSUlLa/O3nJxo3bpzRtWtX323+K1asMOLi4oxp06b52nCez05FRYWxefNmY/PmzYYk4+mnnzY2b95sfPfdd4ZhtMx5LS0tNeLj441bb73V2Lp1q7Fs2TIjMjKS2/zPNc8995zRvXt3Izw83BgyZIjxySefmF1SqyGp0dcrr7zia3P06FHjN7/5jdG+fXsjMjLSuP766429e/f67Wfnzp3GVVddZURERBhxcXHG1KlTjZqamiAfTevSMCBxnlvOW2+9ZfTt29dwOBxG7969jcWLF/ut93g8xsyZM434+HjD4XAYV1xxhbF9+3a/NgcOHDBuueUWIyoqyoiJiTHGjx9vVFRUBPMwQlp5ebkxadIko3v37obT6TTOO+8846GHHvK7bZzzfHY++OCDRv9dHjdunGEYLXdeP/30U2P48OGGw+EwunbtasyZM+cH124xjBOmCgUAAABjkAAAABoiIAEAADRAQAIAAGiAgAQAANAAAQkAAKABAhIAAEADBCQAAIAGCEgAAAANEJAAnPN69uypefPmmV0GgFaEgAQgZFgsltO+fve7353VftevX6+JEyf+oNoKCgr0i1/8QomJiXI6nerWrZuuu+46bdu2TZK0c+dOWSwWbdmy5Qd9D4DQYDe7AACot3fvXt/7N954Q9nZ2X5Ps4+KivK9NwxDbrdbdvuZ/xnr1KnTD6qrpqZGP/3pT3XBBRdoxYoV6tKli77//nu9++67Ki0t/UH7BhCa6EECEDISEhJ8L5fLJYvF4vu8bds2RUdH691339WgQYPkcDj08ccf69tvv9V1112n+Ph4RUVFafDgwXr//ff99tvwEpvFYtFLL72k66+/XpGRkUpJSdGbb755yro+//xzffvtt3r++ec1dOhQ9ejRQ5dccolmz56toUOHSpKSk5MlSQMHDpTFYtFll13m2/6ll15Snz595HQ61bt3bz3//PO+dfU9T8uWLdOwYcPkdDrVt29fffjhhy1wRgGcLQISgFblgQce0Jw5c/Tll1/q4osv1uHDh3X11VcrLy9Pmzdv1pVXXqlRo0apsLDwtPt5+OGH9Z//+Z/697//rauvvlpjxozRwYMHG23bqVMnWa1W/fWvf5Xb7W60zbp16yRJ77//vvbu3asVK1ZIkl5//XVlZ2frscce05dffqnf//73mjlzpl599VW/7e+//35NnTpVmzdvVnp6ukaNGqUDBw409/QAaCkGAISgV155xXC5XL7PH3zwgSHJWLly5Rm3veiii4znnnvO97lHjx7GM8884/ssyZgxY4bv8+HDhw1JxrvvvnvKfS5YsMCIjIw0oqOjjcsvv9x45JFHjG+//da3vqCgwJBkbN682W+7888/31i6dKnfskcffdRIT0/3227OnDm+9TU1NUa3bt2Mxx9//IzHCiAw6EEC0Kqkpqb6fT58+LDuu+8+9enTR7GxsYqKitKXX355xh6kiy++2Pe+Xbt2iomJ0b59+07Z/s4771RRUZFef/11paena/ny5brooou0atWqU25TWVmpb7/9VhMmTFBUVJTvNXv2bH377bd+bdPT033v7Xa7UlNT9eWXX572GAAEDoO0AbQq7dq18/t83333adWqVXryySfVq1cvRURE6Oc//7mqq6tPu5+wsDC/zxaLRR6P57TbREdHa9SoURo1apRmz56tzMxMzZ49Wz/96U8bbX/48GFJ0osvvqi0tDS/dTab7bTfBcBc9CABaNX+9a9/6bbbbtP111+vfv36KSEhQTt37gz491osFvXu3VuVlZWSpPDwcEnyG6MUHx+vxMRE7dixQ7169fJ71Q/qrvfJJ5/43tfW1mrjxo3q06dPwI8DQOPoQQLQqqWkpGjFihUaNWqULBaLZs6cecaeoObasmWLZs2apVtvvVUXXnihwsPD9eGHH+qPf/yjfvvb30qSOnfurIiICOXm5qpbt25yOp1yuVx6+OGHdc8998jlcunKK69UVVWVNmzYoEOHDmnKlCm+71i4cKFSUlLUp08fPfPMMzp06JB++ctftuhxAGg6AhKAVu3pp5/WL3/5Sw0bNkxxcXH67W9/q/Ly8hb9jm7duqlnz556+OGHfbfl13++9957JXnHDc2fP1+PPPKIsrOzdemll+of//iH/uu//kuRkZF64okndP/996tdu3bq16+fJk+e7Pcdc+bM0Zw5c7Rlyxb16tVLb775puLi4lr0OAA0ncUwDMPsIgCgrdq5c6eSk5O1efNmDRgwwOxyANRhDBIAAEADBCQAAIAGuMQGAADQAD1IAAAADRCQAAAAGiAgAQAANEBAAgAAaICABAAA0AABCQAAoAECEgAAQAMEJAAAgAb+P/QwotYr0/w/AAAAAElFTkSuQmCC"
     },
     "metadata": {},
     "output_type": "display_data",
     "jetTransient": {
      "display_id": null
     }
    }
   ],
   "execution_count": 51
  },
  {
   "cell_type": "code",
   "id": "8a49e917",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:41.270430Z",
     "start_time": "2025-10-06T05:15:41.039310Z"
    }
   },
   "source": [
    "# PolynomialDecay scheduler\n",
    "\n",
    "rates = bp.optim.PolynomialDecayLR(lr=0.01, decay_steps=10, final_lr=0.0001)(steps)\n",
    "show(steps, rates)"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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lClTNGTIEHXv3l2333677rnnHuXk5EjiPDeWhjqvjfX/EwKSTYSHhys5OVkFBQXmNp/Pp4KCAqWlpVk4s/OHYRi6++679Ze//EVr1649peSanJysJk2aBJzjnTt3qqSkxDzHaWlp+vjjjwP+g8zPz1d0dPQpv6guVNdee60+/vhjbdmyxXylpKRo2LBh5t85zw3jqquuOuVWFZ9++qk6duwoSUpISJDH4wk41xUVFVq3bl3AuS4rK9OmTZvMMWvXrpXP51NqamoIvoX9ffvtt3I6A38dulwu+Xw+SZznxtJQ5zUtLU3vvvuujh49ao7Jz8/XZZdddtaX1ySxzN9Oli1bZkRERBhLliwxPvnkE2PMmDFGy5YtA1b64PR+85vfGG632/j73/9ufPXVV+br22+/NcfcddddRocOHYy1a9caGzduNNLS0oy0tDRzv3/5+S9+8Qtjy5YtRl5ennHxxRez/PxHnLyKzTA4zw1l/fr1RlhYmPHII48Yn332mfHqq68aTZs2Nf7nf/7HHDN79myjZcuWxl//+lfjn//8p3HTTTfVuUy6Z8+exrp164z333/fSExMvOCXn59sxIgRRrt27cxl/itXrjRiYmKMyZMnm2M4z2fn8OHDRlFRkVFUVGRIMh5//HGjqKjI+Ne//mUYRsOc17KyMiM2Nta4/fbbja1btxrLli0zmjZtyjL/fzdPPfWU0aFDByM8PNzo3bu38eGHH1o9pfOGpDpfL730kjnmu+++M377298arVq1Mpo2bWrcfPPNxldffRVwnN27dxvXX3+9ERUVZcTExBiTJk0yjh49GuJvc36pHZA4zw3n9ddfN7p162ZEREQYXbp0MRYvXhyw3+fzGTNmzDBiY2ONiIgI49prrzV27twZMObrr782hg4dajRv3tyIjo42Ro4caRw+fDiUX8PWKioqjAkTJhgdOnQwIiMjjUsuucR44IEHApaNc57Pzttvv13n/5dHjBhhGEbDndePPvrI6NevnxEREWG0a9fOmD179jnP3WEYJ90qFAAAAPQgAQAA1EZAAgAAqIWABAAAUAsBCQAAoBYCEgAAQC0EJAAAgFoISAAAALUQkAAAAGohIAH4t9epUyfNnz/f6mkAOI8QkADYhsPhOOPrd7/73Vkdd8OGDRozZsw5za24uFj/9V//pbi4OEVGRqp9+/a66aabtGPHDknS7t275XA4tGXLlnP6HAD2EGb1BADA76uvvjL/vnz5cmVnZwc8zb558+bm3w3DUE1NjcLCfvx/YxdffPE5zevo0aP6+c9/rssuu0wrV65U27Zt9eWXX+qNN95QWVnZOR0bgD1RQQJgGx6Px3y53W45HA7z5x07dqhFixZ64403lJycrIiICL3//vv64osvdNNNNyk2NlbNmzdXr1699NZbbwUct/YlNofDoeeff14333yzmjZtqsTERL322munnde2bdv0xRdf6Omnn1afPn3UsWNHXXXVVZo1a5b69OkjSUpISJAk9ezZUw6HQz/96U/N9z///PPq2rWrIiMj1aVLFz399NPmPn/ladmyZerbt68iIyPVrVs3vfPOOw1wRgGcLQISgPPKlClTNHv2bG3fvl1XXnmljhw5ogEDBqigoEBFRUW67rrrNGjQIJWUlJzxOA8++KB+9atf6Z///KcGDBigYcOG6dChQ3WOvfjii+V0OvXnP/9ZNTU1dY5Zv369JOmtt97SV199pZUrV0qSXn31VWVnZ+uRRx7R9u3b9fvf/14zZszQyy+/HPD+++67T5MmTVJRUZHS0tI0aNAgff3118GeHgANxQAAG3rppZcMt9tt/vz2228bkoxVq1b96HuvuOIK46mnnjJ/7tixo/HEE0+YP0sypk+fbv585MgRQ5LxxhtvnPaYCxcuNJo2bWq0aNHCuOaaa4yHHnrI+OKLL8z9xcXFhiSjqKgo4H2XXnqpsXTp0oBtDz/8sJGWlhbwvtmzZ5v7jx49arRv39549NFHf/S7AmgcVJAAnFdSUlICfj5y5Ijuvfdede3aVS1btlTz5s21ffv2H60gXXnllebfmzVrpujoaO3fv/+048eOHSuv16tXX31VaWlpWrFiha644grl5+ef9j2VlZX64osvNGrUKDVv3tx8zZo1S1988UXA2LS0NPPvYWFhSklJ0fbt28/4HQA0Hpq0AZxXmjVrFvDzvffeq/z8fD322GPq3LmzoqKi9Mtf/lLV1dVnPE6TJk0CfnY4HPL5fGd8T4sWLTRo0CANGjRIs2bNUkZGhmbNmqWf//zndY4/cuSIJOm5555TampqwD6Xy3XGzwJgLSpIAM5r//jHP3THHXfo5ptvVvfu3eXxeLR79+5G/1yHw6EuXbqosrJSkhQeHi5JAT1KsbGxiouL065du9S5c+eAl7+p2+/DDz80/37s2DFt2rRJXbt2bfTvAaBuVJAAnNcSExO1cuVKDRo0SA6HQzNmzPjRSlCwtmzZopkzZ+r222/X5ZdfrvDwcL3zzjt68cUXdf/990uS2rRpo6ioKOXl5al9+/aKjIyU2+3Wgw8+qPHjx8vtduu6665TVVWVNm7cqG+++UZZWVnmZyxatEiJiYnq2rWrnnjiCX3zzTe68847G/R7AKg/AhKA89rjjz+uO++8U3379lVMTIzuv/9+VVRUNOhntG/fXp06ddKDDz5oLsv3/3zPPfdIOt43tGDBAj300EPKzs7W1Vdfrb///e/67//+bzVt2lRz587Vfffdp2bNmql79+6aOHFiwGfMnj1bs2fP1pYtW9S5c2e99tpriomJadDvAaD+HIZhGFZPAgAuVLt371ZCQoKKioqUlJRk9XQAnEAPEgAAQC0EJAAAgFq4xAYAAFALFSQAAIBaCEgAAAC1EJAAAABqISABAADUQkACAACohYAEAABQCwEJAACgFgISAABALf8fWTwpVX8SNJ0AAAAASUVORK5CYII="
     },
     "metadata": {},
     "output_type": "display_data",
     "jetTransient": {
      "display_id": null
     }
    }
   ],
   "execution_count": 52
  },
  {
   "cell_type": "markdown",
   "id": "3ef61151",
   "metadata": {},
   "source": [
    "## Creating a Self-Customized Scheduler"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9dd71dab",
   "metadata": {},
   "source": [
    "If users try to implement their own scheduler, simply inherit from ``bm.optimizers.Scheduler`` class and override the following methods:\n",
    "\n",
    "- ``__init__()``: the init function. \n",
    "- ``__call__(i=None)``: the learning rate value evalution. "
   ]
  },
  {
   "cell_type": "code",
   "id": "7466e67c",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T05:15:41.288035Z",
     "start_time": "2025-10-06T05:15:41.283285Z"
    }
   },
   "source": [
    "class CustomizeScheduler(bp.optim.Scheduler):\n",
    "    def __init__(self, lr, *params, **other_params):\n",
    "        super(CustomizeScheduler, self).__init__(lr)\n",
    "        \n",
    "        # customize your initialization\n",
    "        \n",
    "    def __call__(self, i=None):\n",
    "        # customize your update logic\n",
    "        pass"
   ],
   "outputs": [],
   "execution_count": 53
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.1"
  },
  "latex_envs": {
   "LaTeX_envs_menu_present": true,
   "autoclose": false,
   "autocomplete": true,
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 1,
   "hotkeys": {
    "equation": "Ctrl-E",
    "itemize": "Ctrl-I"
   },
   "labels_anchors": false,
   "latex_user_defs": false,
   "report_style_numbering": false,
   "user_envs_cfg": false
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
